package com.lzq.mq.broker.netty.nameserver;

import com.alibaba.fastjson2.JSON;
import com.lzq.mq.broker.cache.CommonCache;
import com.lzq.mq.common.coder.TcpMsg;
import com.lzq.mq.common.dto.HeartBeatDTO;
import com.lzq.mq.common.enums.NameServerEventCode;
import com.lzq.mq.common.enums.NameServerResponseCode;
import com.lzq.mq.common.remote.NameServerNettyRemoteClient;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 心跳任务
 */
@Slf4j
public class HeartBeatTaskManager {

    private AtomicInteger flag = new AtomicInteger(0);

    public void startTask() {
        if (!flag.compareAndSet(0, 1)) {
            return;
        }
        Thread thread = new Thread(new HeartBeatRequsetTask());
        thread.setName("心跳检测任务");
        thread.start();
    }


    private class HeartBeatRequsetTask implements Runnable {

        @Override
        public void run() {
            log.info("启动心跳任务");
            while (true) {

                try {
                    TimeUnit.SECONDS.sleep(3);
                    //心跳包不需要额外透传过多的参数，只需要告诉nameserver这个channel依然存活即可
                    NameServerNettyRemoteClient nameServerNettyRemoteClient = CommonCache.getNameServerClient().getNameServerNettyRemoteClient();
                    HeartBeatDTO heartBeatDTO = new HeartBeatDTO();
                    heartBeatDTO.setMsgId(UUID.randomUUID().toString());
                    TcpMsg tcpMsg = new TcpMsg(NameServerEventCode.HEART_BEAT.getCode(), JSON.toJSONBytes(heartBeatDTO));
                    TcpMsg heartBeatResp = nameServerNettyRemoteClient.sendSyncMsg(tcpMsg,heartBeatDTO.getMsgId());
                    if(NameServerResponseCode.HEART_BEAT_SUCCESS.getCode() != heartBeatResp.getCode()) {
                        log.error("心跳响应异常:{}",heartBeatResp.getCode());
                    }
                } catch (Exception e) {
                    log.error("心跳任务异常", e);
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
